#include "EngineHeader.h"
#include "mdxModel.h"
#include "mdxParser.h"

namespace LSH
{

    const CM_TCHAR* getProjectPath()
    {
        static String projectDirPath;
        CM_TCHAR szProjectDirPath[MAX_PATH];
        HMODULE module = GetModuleHandle(NULL);
        GetModuleFileName(module, szProjectDirPath, MAX_PATH);
        projectDirPath = szProjectDirPath;
        while(true)
        {
            size_t p = projectDirPath.find(_T("\\"));
            if(p == String::npos)
            {
                break;
            }
            else
            {
                projectDirPath.replace(p, 1, _T("/"));
            }
        }

        size_t pos = projectDirPath.rfind(_T("/"));
        projectDirPath.resize(pos);

        pos = projectDirPath.rfind(_T('/'));
        projectDirPath.resize(pos);

        return projectDirPath.c_str();
    }


    using namespace Graphics;
    struct mdxVertex
    {
        mdxFloat3 pos;
        mdxFloat3 n;
        mdxFloat2 v;
    
        static const int FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
   };


    mdxModel::mdxModel(void)
    {
        _vb = NULL;
        _ib = NULL;
        _tex = NULL;
    }

    mdxModel::~mdxModel(void)
    {
        if(_vb)
        {
            CM_DELETE(_vb);
        }
        if(_ib)
        {
            CM_DELETE(_ib);
        }
    }

    void mdxModel::render()
    {
        _vb->setAsStreamSource();

        _ib->setAsIndicesSource();

        IDirect3DDevice9* pD3dDevice = Render::getSingleton().getD3DDevice();

        pD3dDevice->SetTexture(0, _tex->getTexture());
        pD3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
        pD3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
        pD3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

        pD3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, _vertexCount, 0, _faceCount);
    }

    bool mdxModel::load( String& name )
    {
        MdxParser parser;
        if(! parser.load(name))
        {
            return false;
        }

        _modelPath = name;
        size_t pos = _modelPath.rfind(_T('/'));
        if(pos != String::npos)
        {
            _modelPath.resize(pos + 1);
        }
        else
        {
            pos = _modelPath.rfind(_T('\\'));
            if(pos != String::npos)
            {
                _modelPath.resize(pos + 1);
            }
            else
            {
                assert(0);
            }
        }

        int count = parser._mdxGeometriSet.geometrics.size();
        for(int n = 0; n < count; n++)
        {
            const MdxGeometric& geoset = parser._mdxGeometriSet.geometrics[n];
            _vertexCount = geoset.vertexPositions.size();
            int norCnt = geoset.vertexNormals.size();
            int texCnt = geoset.vertexTexturePositions.size();

            if(_vertexCount != norCnt)
            {
                return false;
            }
            else if(_vertexCount != texCnt)
            {
                return false;
            }

            mdxVertex* pVertexArray = new mdxVertex[_vertexCount];

            for(int i = 0; i < _vertexCount; i++)
            {
                pVertexArray[i].pos = geoset.vertexPositions[i];
                pVertexArray[i].n = geoset.vertexNormals[i];
                pVertexArray[i].v = geoset.vertexTexturePositions[i];
            }

            int byteSize = sizeof(mdxVertex) * _vertexCount;

            _vb = CM_NEW Graphics::VertexBuffer;

            _vb->create(byteSize, _vertexCount, mdxVertex::FVF);

            _vb->map((void*)pVertexArray, byteSize);

            _faceCount = geoset.face.size();
            mdxFace* pFaceArray = new mdxFace[_faceCount];
            for(int j = 0; j < _faceCount; j++)
            {
                pFaceArray[j] =  geoset.face[j];
            }

            byteSize = _faceCount * 3 * sizeof(WORD);

            _ib = CM_NEW Graphics::IndexBuffer;

            _ib->create(byteSize);

            _ib->map((void*)pFaceArray, byteSize);

        }

        int texCount =  parser._mdxTextureSet.textures.size();
        if(texCount > 0)
        {
            for(int i = 0; i < texCount; i++)
            {
                MdxTexture& mdxTex = parser._mdxTextureSet.textures[i];
                String name = getProjectPath();
                name += _T("/");
                name.append(mdxTex.name);
                while(true)
                {
                    size_t p = name.find(_T('\\'));
                    if(p == String::npos)
                    {
                        break;
                    }
                    else
                    {
                        name.replace(p , 1, _T("/"));
                    }
                }
                if(name.size() > 0)
                {
                    _tex = Graphics::TextureManager::getSingleton().loadTextureFormFile(name);
                    assert(_tex);
                }

            }
        }

        return true;
    }

} // end LSH




